package com.meme.editor.model.sprite2d;

import org.apache.log4j.Logger;

import com.meme.editor.EntityObject;
import com.meme.editor.EntityRefLink;
import com.meme.editor.property.PropertyFactory;

public abstract class ModuleRef extends Module 
{
	static Logger logger = Logger.getLogger (ModuleRef.class);
	
	final static String GroupName_ModuleRefGroup = "Module Ref";
	final static String PropertyName_ModulePath        = "Module";

	
	// Module mModule;
	EntityRefLink mRefedModule;

	public ModuleRef ()
	{
		this (null, null, null);
	}
	
	public ModuleRef (Module module)
	{
		this (null, null, module);
	}
	
	public ModuleRef (EntityObject parent)
	{
		this (null, parent, null);
	}
	
	public ModuleRef (EntityObject parent, Module module)
	{
		this (null, parent, module);
	}
	
	public ModuleRef (String name, EntityObject parent)
	{
		this (name, parent, null);
	}
	
	public ModuleRef (String name, EntityObject parent, Module module)
	{
		super (name, parent);
		
		mRefedModule = new EntityRefLink (this);

		createPublicProperty (GroupName_ModuleRefGroup, PropertyName_ModulePath, PropertyFactory.ValueType_String )
		.setEditable (false);

		setModule (module);
	}
	
	public void setModule (Module module)
	{
		//mModule    = module;
		mRefedModule.setRefedEntity (module);
		
		// already called in setRefedEntity
		//notifyEntityRefLinkModified (mRefedModule);
	}
	
	public Module getModule ()
	{
		//return mModule;
		return (Module) ( mRefedModule.getRefedEntity() );
	}
	

	
	// for ModuleGroupViews
	public boolean checkReferability (EntityObject refed)
	{
		return checkReferability (mRefedModule, refed);
	}
	
	@Override
	public boolean checkReferability (EntityRefLink link, EntityObject refed)
	{
		// to do: rewrite this method ...
		
		if ( link == mRefedModule && refed != null )
		{
			Module module = (Module) refed;
			
			if ( this instanceof ModulePart )
			{
				logger.assertLog (getParent() instanceof CompositedModule, "parent should be a CompositedModule.");
				
				CompositedModule parent = (CompositedModule) getParent ();
				
				if ( getParent() == module )
					return false;
				
				if ( module instanceof CompositedModule )
				{
					CompositedModule compositedModule = (CompositedModule) module;
					if ( compositedModule.containsModuleAsPartInSubTree ( parent ) )
						return false;
				}
			}
			else if ( this instanceof Tiled2dModule )
			{
				if ( this == module )
					return false;
				
				// if ( module instanceof ModuleRef )
				//{
				//	// ..., recursive, ...
				//}
				
				if ( module instanceof CompositedModule )
				{
					CompositedModule compositedModule = (CompositedModule) module;
					if ( compositedModule.containsModuleAsPartInSubTree ( this ) )
						return false;
				}
			}
		}
		
		return true;
	}
	
	@Override
	public void notifyEntityRefLinkModified (EntityRefLink link)
	{
		String path;
		if ( getModule () == null )
			path = "";
		else
			path = getModule ().getParent().getIndex() + "/" + getModule ().toString();
		
		changePublicPropertyValue ( GroupName_ModuleRefGroup, PropertyName_ModulePath, path );
	}

	@Override
	public boolean isImageHybird ()
	{
		if ( getModule () == null )
			return false;
		
		return getModule ().isImageHybird();
	}

	@Override
	public boolean isPaletteHybird ()
	{
		if ( getModule () == null )
			return false;
		
		return getModule ().isPaletteHybird();
	}
	

}
